package cn.pconline.autoclub.service;

import cn.pconline.autoclub.config.SystemConfig;
import cn.pconline.autoclub.entity.BbsActionLog;
import cn.pconline.autoclub.entity.ClubIntegral;
import cn.pconline.autoclub.entity.ClubMember;
import cn.pconline.autoclub.entity.Topic;
import cn.pconline.autoclub.entity.TopicImage;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.util.DateUtils;
import cn.pconline.r.client.EntityBuilder;
import cn.pconline.r.client.RequestCallback;
import cn.pconline.r.client.ResponseExtractor;
import cn.pconline.r.client.SimpleHttpTemplate;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.util.EntityUtils;
import org.gelivable.dao.GeliDao;
import org.gelivable.dao.GeliOrm;
import org.gelivable.dao.SqlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 论坛操作服务类
 */
public class BbsActionLogService {

    private static final Logger log = LoggerFactory.getLogger(BbsActionLogService.class);
    @Autowired
    private GeliDao geliDao;
    @Autowired
    private GeliOrm geliOrm;
    @Autowired
    private SimpleHttpTemplate simpleHttpTemplate;
    @Autowired
    private SystemConfig systemConfig;
    //@Autowired
    //private UserAuth userAuth;
    @Autowired
    private TopicService topicService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private UserService userService;
    @Autowired
    private PetrolService petrolService;
    @Autowired
    private ClubService clubService;
    @Autowired
    private IntfService intfService;

    /**
     * 创建
     *
     * @param bbsActionLog
     */
    public void create(BbsActionLog bbsActionLog) {
        geliDao.create(bbsActionLog);
    }

    /**
     * 根据logId查找Log 暂时忽略createTime参数
     *
     * @param logId
     */
    public BbsActionLog find(long logId, long createTime) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select * from ").appendSql(geliOrm.getTableName(BbsActionLog.class, createTime));
        sql.appendSql(" where log_id = ").appendValue(logId);
        return geliDao.findFirst(BbsActionLog.class, sql.getSql(), sql.getValues());
    }

    /**
     * 通知论坛更改log状态,提供参数logId
     *
     * @param bbsActionLog
     */
    public void changeBbsStatus(BbsActionLog bbsActionLog) {
        String url = systemConfig.getBbsRoot() + "/plugins/autoclub/receive.do";
        String result = simpleHttpTemplate.post(url, null,
                new RequestCallback() {
                    @Override
                    public void doWithRequest(HttpUriRequest request) throws IOException {
                        //request.addHeader("POE", "123");
                    }
                },
                new ResponseExtractor<String>() {
                    @Override
                    public String extractData(HttpResponse response) throws IOException {
                        StatusLine statusLine = response.getStatusLine();
                        if (statusLine.getStatusCode() == 200) {
                            return EntityUtils.toString(response.getEntity());
                        } else {
                            throw new IOException(statusLine.toString());
                        }
                    }
                },
                EntityBuilder.entity().param("logId", bbsActionLog.getLogId()).build());
    }

    /**
     * 处理论坛传过来的日志
     *
     * TODO 定义typeId枚举常量，整理下同步逻辑
     *
     * @param bbsActionLog
     * @param typeId
     */
    public void service(BbsActionLog bbsActionLog, int typeId) {

        //验证用户
        if (bbsActionLog == null || bbsActionLog.getUserId() <= 0L) {
            return;
        }

        //验证log是否已经存在
        BbsActionLog existLog = find(
                bbsActionLog.getLogId(), bbsActionLog.getCreateAt().getTime());
        if (existLog != null) {
            changeBbsStatus(bbsActionLog);
            return;
        }
        
        /*
         * 过滤屏蔽版块
         * http://bbs.pcauto.com.cn/forum-15253.html
         * http://bbs.pcauto.com.cn/forum-15252.html
         * http://bbs.pcauto.com.cn/forum-21245.html
         * http://bbs.pcauto.com.cn/forum-19017.html
         * http://bbs.pcauto.com.cn/forum-19375.html
         */
        /*long[] filteForums = {15253, 15252, 21245, 19017, 19375};
        long forumId = bbsActionLog.getForumId();
        //是屏蔽版块并且回帖操作，发完消息返回，不做加油值
        if(ArrayUtils.contains(filteForums, forumId)) {
            if(typeId == REPLY_TOPIC_TYPE) {//回帖
                PostReply postReply = parseActionLog2PostReply(bbsActionLog);
                dynaService.setJson4BipBbsTopics(postReply);
            }
            return;
        }*/
        

        User user = userService.authUser(bbsActionLog.getUserId());
        //验证用户是否有车友会，回帖相关操作可以直接跳过
        List<ClubMember> clubList = memberService.listClubMemberByUser(user.getUid());
        if (clubList == null || clubList.isEmpty()) {
            if (typeId == 106 || typeId == 112) {
                replyTopic(bbsActionLog);
            } else if (typeId == 107 && bbsActionLog.getContent() != null) {
                deletePost(bbsActionLog);
            }
            create(bbsActionLog);
            changeBbsStatus(bbsActionLog);
            return;
        }
        create(bbsActionLog);
        switch (typeId) {
            case 100:
                //创建主帖
                createTopic(bbsActionLog, clubList);
                break;
            case 101:
                //删除主帖
                deleteTopic(bbsActionLog, clubList);
                break;
            case 102:
                //设置精华
                setPick(bbsActionLog, clubList);
                break;
            case 103:
                //取消精华
                removePick(bbsActionLog, clubList);
                break;
            case 104:
                //设置推荐
                setRecommend(bbsActionLog, clubList);
                break;
            case 105:
                //取消推荐
                removeRecommend(bbsActionLog, clubList);
                break;
            case 106:
                //回帖
                addReplyTopicPetrol(bbsActionLog, clubList);
                replyTopic(bbsActionLog);
                break;
            case 107:
                //删除回帖
                delPostPetrol(bbsActionLog, clubList);
                deletePost(bbsActionLog);
                break;
            case 108:
                //车主认证
                setUserVip(bbsActionLog, clubList);
                break;
            case 109:
                //取消车主认证
                removeUserVip(bbsActionLog, clubList);
                break;
            case 110:
                //修改帖子
                updateTopic(bbsActionLog, clubList);
                break;
            case 111:
                //恢复主帖
                createTopic(bbsActionLog, clubList);
                break;
            case 112:
                //恢复回帖
                addReplyTopicPetrol(bbsActionLog, clubList);
                replyTopic(bbsActionLog);
                break;
            case 113:
                //修改回复内容
                break;
            default:
                log.error("接收日志时没有相对应的typeId:" + typeId + ","
                        + " logId:" + bbsActionLog.getLogId()
                        + " topicId:" + bbsActionLog.getTopicId()
                        + " forumId:" + bbsActionLog.getForumId()
                        + " userId:" + bbsActionLog.getUserId()
                        + " typeId:" + typeId
                        + " createAt:" + bbsActionLog.getCreateAt().getTime()
                        + " content:" + bbsActionLog.getContent());
                throw new RuntimeException("接收日志时没有相对应的typeId:" + typeId);
        }
        changeBbsStatus(bbsActionLog);
    }

    /**
     * 论坛创建帖子操作
     *
     * @param bbsActionLog
     */
    public void createTopic(BbsActionLog bbsActionLog, List<ClubMember> clubList) {
        for (ClubMember club : clubList) {
            Topic topic = parseActionLog2Topic(bbsActionLog, club.getClubId());
            topicService.createTopic(topic);
            List<TopicImage> topicImages = parseActionLog2TopicImages(bbsActionLog);
            topicService.createTopicImage(topicImages);
        }
    }

    public void deleteTopic(BbsActionLog bbsActionLog, List<ClubMember> clubList) {
        for (ClubMember club : clubList) {
            topicService.deleteTopic(bbsActionLog.getTopicId(), club.getClubId());
            topicService.deleteTopicImage(bbsActionLog.getTopicId());
        }
    }

    public void setPick(BbsActionLog bbsActionLog, List<ClubMember> clubList) {
        for (ClubMember club : clubList) {
            topicService.setPick(bbsActionLog.getTopicId(), club.getClubId());
        }
    }

    public void removePick(BbsActionLog bbsActionLog, List<ClubMember> clubList) {
        for (ClubMember club : clubList) {
            topicService.removePick(bbsActionLog.getTopicId(), club.getClubId());
        }
    }

    public void setRecommend(BbsActionLog bbsActionLog, List<ClubMember> clubList) {
        for (ClubMember club : clubList) {
            topicService.setRecommend(bbsActionLog.getTopicId(), club.getClubId());
        }
    }

    public void removeRecommend(BbsActionLog bbsActionLog, List<ClubMember> clubList) {
        for (ClubMember club : clubList) {
            topicService.removeRecommend(bbsActionLog.getTopicId(), club.getClubId());
        }
    }

    public void replyTopic(BbsActionLog bbsActionLog) {
        long topicUserId = parseTopicUserId(bbsActionLog);
        List<ClubMember> clubTopicMemberList = memberService.listClubMemberByUser(topicUserId);
        for (ClubMember member : clubTopicMemberList) {
            topicService.replyTopic(bbsActionLog.getTopicId(),
                    member.getClubId(), bbsActionLog.getUserId(),
                    parseLastPostAt(bbsActionLog));
        }
    }

    public void addReplyTopicPetrol(BbsActionLog bbsActionLog, List<ClubMember> clubPostMemberList) {
        for (ClubMember member : clubPostMemberList) {
            topicService.addReplyTopicPetrol(member.getClubId(), bbsActionLog.getUserId(),
                    parsePostAgent(bbsActionLog));
        }
    }

    public void delPostPetrol(BbsActionLog bbsActionLog, List<ClubMember> clubPostMemberList) {
        for (ClubMember member : clubPostMemberList) {
            topicService.delReplyTopicPetrol(member.getClubId(), bbsActionLog.getUserId(),
                    parsePostAgent(bbsActionLog));
        }
    }

    public void deletePost(BbsActionLog bbsActionLog) {
        long topicUserId = parseTopicUserId(bbsActionLog);
        List<ClubMember> clubTopicMemberList = memberService.listClubMemberByUser(topicUserId);
        if (clubTopicMemberList != null && !clubTopicMemberList.isEmpty()) {
            for (ClubMember member : clubTopicMemberList) {
                topicService.deletePost(bbsActionLog.getTopicId(),
                        member.getClubId(), bbsActionLog.getUserId());
            }
        }
    }

    /**
     * 车主认证
     *
     * @param bbsActionLog
     * @param memberList
     */
    public void setUserVip(BbsActionLog bbsActionLog, List<ClubMember> memberList) {
        User user = userService.findUser(bbsActionLog.getUserId());
        if (user != null && user.getVip() != 1) {
            userService.setVip(bbsActionLog.getUserId(), bbsActionLog.getContent());
            for (ClubMember member : memberList) {
                clubService.increaseVipNum(member.getClubId());
                // TODO 待优化
                ClubIntegral integral = petrolService.getById(PetrolService.ADD_CLUB_PETROL_ITEM_VIP);
                petrolService.addToClubWithinLimit(member.getClubId(), integral.getIntegralId(), integral.getPetrol(), integral.getName(), false);
            }

        }
    }

    /**
     * 取消车主认证
     *
     * @param bbsActionLog
     * @param memberList
     */
    public void removeUserVip(BbsActionLog bbsActionLog, List<ClubMember> memberList) {
        User user = userService.findUser(bbsActionLog.getUserId());
        if (user != null && user.getVip() != 0) {
            userService.cancelVip(bbsActionLog.getUserId());
            for (ClubMember member : memberList) {
                clubService.decreaseVipNum(member.getClubId());
                ClubIntegral integral = petrolService.getById(PetrolService.ADD_CLUB_PETROL_ITEM_VIP_QUIT);
                petrolService.addToClubWithinLimit(member.getClubId(), integral.getIntegralId(), integral.getPetrol(), integral.getName(), false);
            }
        }
    }

    public void updateTopic(BbsActionLog bbsActionLog, List<ClubMember> memberList) {
        for (ClubMember member : memberList) {
            Topic topic = parseActionLog2Topic(bbsActionLog, member.getClubId());
            List<TopicImage> topicImages = parseActionLog2TopicImages(bbsActionLog);
            topicService.updateTopic(topic.getTopicId(), topic.getClubId(), topic.getTopicTitle(),
                    topic.getMessage(), topic.getImage1(), topic.getImage2(), topic.getImage3());
            topicService.updateTopicImage(topicImages);
        }
    }

    /**
     * actionLog转topicImages
     *
     * @param bbsActionLog
     * @param clubId
     * @return
     */
    private List<TopicImage> parseActionLog2TopicImages(BbsActionLog bbsActionLog) {
        JSONObject jsonObject = parseContent(bbsActionLog);
        List<TopicImage> list = new ArrayList<TopicImage>();
        TopicImage image1 = new TopicImage();
        image1.setTopicId(bbsActionLog.getTopicId());
        image1.setUrl(StringUtils.defaultString(jsonObject.getString("image1")));
        image1.setHeight(jsonObject.getIntValue("height1"));
        image1.setWidth(jsonObject.getIntValue("width1"));
        image1.setSeq(1);
        if (!StringUtils.isBlank(image1.getUrl())) {
            list.add(image1);
        }
        TopicImage image2 = new TopicImage();
        image2.setTopicId(bbsActionLog.getTopicId());
        image2.setUrl(StringUtils.defaultString(jsonObject.getString("image2")));
        image2.setHeight(jsonObject.getIntValue("height2"));
        image2.setWidth(jsonObject.getIntValue("width2"));
        image2.setSeq(2);
        if (!StringUtils.isBlank(image2.getUrl())) {
            list.add(image2);
        }
        TopicImage image3 = new TopicImage();
        image3.setTopicId(bbsActionLog.getTopicId());
        image3.setUrl(StringUtils.defaultString(jsonObject.getString("image3")));
        image3.setHeight(jsonObject.getIntValue("height3"));
        image3.setWidth(jsonObject.getIntValue("width3"));
        image3.setSeq(3);
        if (!StringUtils.isBlank(image3.getUrl())) {
            list.add(image3);
        }
        return list;
    }

    /**
     * actionLog转topic,只有创建帖子的时候有效
     *
     * @param bbsActionLog
     * @param clubId
     * @return
     */
    private Topic parseActionLog2Topic(BbsActionLog bbsActionLog, long clubId) {
        JSONObject jsonObject = parseContent(bbsActionLog);
        Topic topic = new Topic();
        topic.setTopicId(bbsActionLog.getTopicId());
        topic.setClubId(clubId);
        topic.setForumId(bbsActionLog.getForumId());
        topic.setUserId(bbsActionLog.getUserId());
        topic.setForumName(StringUtils.defaultString(jsonObject.getString("forumName")));
        topic.setImage1(StringUtils.defaultString(jsonObject.getString("image1")));
        topic.setImage2(StringUtils.defaultString(jsonObject.getString("image2")));
        topic.setImage3(StringUtils.defaultString(jsonObject.getString("image3")));
        topic.setLastPostAt(new Date(jsonObject.getLongValue("lastPostAt")));
        topic.setCreateDate(new Date(jsonObject.getLongValue("createAt")));
        topic.setLastPostBy(bbsActionLog.getUserId());
        topic.setLastPostName(userService.getNickNameByUserId(bbsActionLog.getUserId()));
        topic.setMessage(StringUtils.defaultString(jsonObject.getString("message")));
        topic.setTopicTitle(StringUtils.defaultString(jsonObject.getString("title")));
        topic.setPick(jsonObject.getIntValue("pick"));
        topic.setRecommend(jsonObject.getIntValue("recommend"));
        topic.setPostCount(jsonObject.getIntValue("postCount"));
        return topic;
    }

    private Date parseLastPostAt(BbsActionLog bbsActionLog) {
        JSONObject jsonObject = parseContent(bbsActionLog);
        Date lastPostAt = jsonObject.getSqlDate("lastPostAt");
        return lastPostAt == null ? DateUtils.getNow() : lastPostAt;
    }

    private JSONObject parseContent(BbsActionLog bbsActionLog) {
        try {
            return JSONObject.parseObject(bbsActionLog.getContent());
        } catch (JSONException e) {
            log.error("parse bbsActionLog content error: {}", bbsActionLog.getContent());
            throw e;
        }
    }

    private int parsePostAgent(BbsActionLog bbsActionLog) {
        JSONObject jsonObject = parseContent(bbsActionLog);
        int agent = jsonObject.getIntValue("agent");
        return agent;
    }

    private long parseTopicUserId(BbsActionLog bbsActionLog) {
        JSONObject jsonObject = parseContent(bbsActionLog);
        long topicUserId = jsonObject.getIntValue("topicUserId");
        return topicUserId;
    }
}
